package com.ruoyi.listener;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.im.entity.YytImJoinup;
import com.ruoyi.common.im.service.YytImJoinupService;
import com.ruoyi.common.im.service.YytImMessageService;
import com.ruoyi.common.pms.entity.YytShopMember;
import com.ruoyi.common.pms.service.YytShopMemberService;
import com.ruoyi.task.VipEndTimeOutTask;
import com.ruoyi.vo.GetMessageVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@ServerEndpoint("/websocket/user/{memberId}")
@Slf4j
public class WebSocketUserListener {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private YytImMessageService yytImMessageService;

    @Autowired
    private YytShopMemberService yytShopMemberService;

    @Autowired
    private YytImJoinupService yytImJoinupService;

    private static WebSocketUserListener task;


    @PostConstruct
    public void init() {
        task = this;
        task.yytImMessageService = this.yytImMessageService;
        task.yytShopMemberService = this.yytShopMemberService;
        task.yytImJoinupService = this.yytImJoinupService;
    }


    //实例一个session，这个session是websocket的session
    private Session session;

    //存放当前用户编号
    private String memberId;



    /**concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。*/
    private static ConcurrentHashMap<String ,WebSocketUserListener> webSocketSet = new ConcurrentHashMap<>();


    @OnOpen
    public void onOpen(Session session, @PathParam("memberId") String memberId) throws IOException {
        this.session = session;
        this.memberId = memberId;
        webSocketSet.put(memberId, this);
        log.info("用户登录：{}", memberId);
    }

    @OnMessage
    public void onMessage(String message) throws IOException {
        log.info("【websocket消息】收到客户端发来的消息:{}", message);
        GetMessageVo getMessageVo = JSON.parseObject(message, GetMessageVo.class);
        // 用户向客服发送数据【0 -> 用户向客服发送消息， 1 -> 客服向用户发送消息】
        if (getMessageVo.getSendType() == 0){
            // 查询接收方客服是否在线
            QueryWrapper<YytImJoinup> wrapper = new QueryWrapper<>();
            wrapper.eq("member_id", getMessageVo.getFromId()).eq("status", 0);
            List<YytImJoinup> imJoinups = task.yytImJoinupService.list(wrapper);
            // 如果该用户已经被接入
            if (imJoinups.size() > 0) {
                getMessageVo.setToId(imJoinups.get(0).getServiceId());
                // 并且该客服是在线的
                if (webSocketSet.containsKey(imJoinups.get(0).getServiceId())){
                    // 给该客服发送消息
                    sendMessageTo(JSON.toJSONString(getMessageVo), imJoinups.get(0).getServiceId());
                }else {
                    task.yytImMessageService.addMessage(JSON.toJSONString(getMessageVo), 0);
                }
            }else{
                // 未被接入，放入公共待接入
                task.yytImMessageService.addMessage(JSON.toJSONString(getMessageVo), 0);
                sendMessageAll(getMessageVo);
            }
        }else {
            sendMessageTo(JSON.toJSONString(getMessageVo), getMessageVo.getToId());
        }
    }


    @OnClose
    public void onClose() {
        if (webSocketSet.containsKey(memberId)) {
            webSocketSet.remove(memberId);
        }
        log.info("用户退出:" + memberId );
    }


    /**
     *  消息发送所有人
     */
    public void sendMessageAll(GetMessageVo message) throws IOException {
        List<String> idByList = task.yytShopMemberService.getMemberIdByList(message.getToId(), 3);
        for (String toId : idByList){
            webSocketSet.get(toId).session.getBasicRemote().sendText(JSON.toJSONString(message));
            log.info("【发送消息店铺所有人】: {}", this.memberId+"向"+toId+"发送消息："+message);
        }
    }


    /**
     *  消息发送指定人
     */
    public void sendMessageTo(String message, String toId) throws IOException {
        //消息发送指定人
        if (webSocketSet.containsKey(toId)){
            webSocketSet.get(toId).session.getBasicRemote().sendText(message);
            task.yytImMessageService.addMessage(message, 1);
            log.info("【发送消息店铺指定人】: {}", this.memberId+"向"+toId+"发送消息："+message);
        }else{
            task.yytImMessageService.addMessage(message, 0);
        }
    }



}
